package seqlist.queue.LeetCode;
//622. 设计循环队列

/**
 * 思想：在走到尾部的时候一定要进行取模操作使它返回到头
 */
public class Num622_MyCircularQueue {
    //定长的数组
    private int[] data;
    //永远指向队首元素的索引
    private int head;
    //永远指向队尾元素的索引
    private int tail;

    //创建有个有参构造方法，根据用户的输入指定数组长度
    public Num622_MyCircularQueue(int k) {
        //因为循环队列要浪费一个空间判断是否已满
        //所以size需要 + 1
        this.data = new int[k + 1];
    }
    //向循环队列插入一个元素。如果成功插入则返回真。
    public boolean enQueue(int value) {
        if(isFull()){
            return false;
        }
        data[tail] = value;
        //tail不能随随便便的向后移，如果末尾是要取模的
        tail = (tail + 1) % data.length;
        return true;
    }
    //从循环队列中删除一个元素。如果成功删除则返回真。
    public boolean deQueue() {
        if(isEmpty()){
            return false;
        }
        //head不能随随便便的向后移，如果末尾是要取模的
        head = (head + 1) % data.length;
        return true;
    }
    //从队首获取元素。如果队列为空，返回 -1 。
    public int Front() {
        if(isEmpty()){
            return -1;
        }
        return data[head];
    }
    //获取队尾元素。如果队列为空，返回 -1
    public int Rear() {
        if(isEmpty()){
            return -1;
        }
        int lastIndex = tail == 0 ? data.length - 1 : tail - 1;
        return data[lastIndex];
    }
    //检查循环队列是否为空。
    public boolean isEmpty() {
        return head == tail;
    }
    //检查循环队列是否已满。
    public boolean isFull() {
        return (tail + 1) % data.length == head;
    }
}
